package tom.client.account;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import tom.client.DialogExec;
import tom.client.Library;
import tom.client.LookupInvDlg;
import tom.client.LookupDialog;
import tom.shared.Customer;
import tom.shared.Invoice;
import tom.shared.Payment;
import tom.shared.Product;
import tom.shared.TaxCalc;
import tom.shared.VchItem;
import tom.shared.Voucher;

import com.google.gwt.cell.client.CheckboxCell;
import com.google.gwt.cell.client.EditTextCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.cell.client.TextInputCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.TabPanel;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.datepicker.client.DateBox;
import com.google.gwt.user.datepicker.client.DateBox.DefaultFormat;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.ValueBoxBase.TextAlignment;
import com.google.gwt.user.client.ui.DoubleBox;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.user.client.ui.ListBox;

public class FormVch extends AbsolutePanel implements DialogExec {

	private enum FormMode {
		Clear, Open, Edit, Insert
	};

	private FormMode mode = FormMode.Clear;

	private void setMode(FormMode m) {
		mode = m;
		lbFormMode.setText(m.toString());
		if (m == FormMode.Clear) {
			btnContact.setEnabled(true);
			btnSearch.setEnabled(true);
			txtContCode.setEnabled(true);

			btnDelItem.setEnabled(false);
			btnPayRemove.setEnabled(false);
			txtSaleDate.setEnabled(false);
			txtShipDate.setEnabled(false);
			// txtDueDate.setEnabled(false);
			// txtProject.setEnabled(false);
			// txtPrjCode.setEnabled(false);
			txtAddr.setEnabled(false);
			txtShipTo.setEnabled(false);
			txtComment.setEnabled(false);
			txtDocRef.setEnabled(false);
			txtCustomer.setEnabled(false);
			txtCode.setEnabled(false);
			txtStatus.setEnabled(false);
			txtBalance.setEnabled(false);
			txtAmtPaid.setEnabled(false);
			txtTotalTax.setEnabled(false);
			txtTotalAmt.setEnabled(false);
			txtTotalPaid.setEnabled(false);
			txtDiscount.setEnabled(false);
			boxPayAmt.setEnabled(false);
			txtPayMethod.setEnabled(false);
			txtCheck.setEnabled(false);
			txtPayMeth.setEnabled(false);
			boxCheckDate.setEnabled(false);
			txtProCode.setEnabled(false);
			txtProName.setEnabled(false);
			boxQty.setEnabled(false);
			boxPrice.setEnabled(false);
			boxDiscount.setEnabled(false);
			btnProduct.setEnabled(false);
			btnStock.setEnabled(false);
			btnSave.setEnabled(false);
			taxRate.setEnabled(false);
		} else if (m == FormMode.Open) {
			btnContact.setEnabled(true);
			btnSearch.setEnabled(true);
			txtContCode.setEnabled(false);

			btnDelItem.setEnabled(false);
			btnPayRemove.setEnabled(false);
			txtSaleDate.setEnabled(false);
			txtShipDate.setEnabled(false);
			// txtDueDate.setEnabled(false);
			// txtProject.setEnabled(false);
			// txtPrjCode.setEnabled(false);
			txtAddr.setEnabled(false);
			txtShipTo.setEnabled(false);
			txtComment.setEnabled(false);
			txtDocRef.setEnabled(false);
			txtCustomer.setEnabled(false);
			txtCode.setEnabled(false);
			txtStatus.setEnabled(false);
			txtBalance.setEnabled(false);
			txtAmtPaid.setEnabled(false);
			txtTotalTax.setEnabled(false);
			txtTotalAmt.setEnabled(false);
			txtTotalPaid.setEnabled(false);
			txtDiscount.setEnabled(false);
			boxPayAmt.setEnabled(false);
			txtPayMethod.setEnabled(false);
			txtCheck.setEnabled(false);
			txtPayMeth.setEnabled(false);
			boxCheckDate.setEnabled(false);
			txtProCode.setEnabled(false);
			txtProName.setEnabled(false);
			boxQty.setEnabled(false);
			boxPrice.setEnabled(false);
			boxDiscount.setEnabled(false);
			btnProduct.setEnabled(false);
			btnStock.setEnabled(false);
			btnSave.setEnabled(false);
			taxRate.setEnabled(false);
		} else if (m == FormMode.Edit || m == FormMode.Insert) {
			btnContact.setEnabled(true);
			btnSearch.setEnabled(true);
			txtContCode.setEnabled(false);

			btnDelItem.setEnabled(true);
			btnPayRemove.setEnabled(true);
			txtSaleDate.setEnabled(true);
			txtShipDate.setEnabled(true);
			// txtDueDate.setEnabled(true);
			// txtProject.setEnabled(true);
			// txtPrjCode.setEnabled(true);
			txtAddr.setEnabled(true);
			txtShipTo.setEnabled(true);
			txtComment.setEnabled(true);
			txtDocRef.setEnabled(true);
			txtCustomer.setEnabled(true);
			txtCode.setEnabled(true);
			txtStatus.setEnabled(true);
			txtBalance.setEnabled(true);
			txtAmtPaid.setEnabled(true);
			txtTotalTax.setEnabled(true);
			txtTotalAmt.setEnabled(true);
			txtTotalPaid.setEnabled(true);
			txtDiscount.setEnabled(true);
			boxPayAmt.setEnabled(true);
			txtPayMethod.setEnabled(true);
			txtCheck.setEnabled(true);
			txtPayMeth.setEnabled(true);
			boxCheckDate.setEnabled(true);
			txtProCode.setEnabled(true);
			txtProName.setEnabled(true);
			boxQty.setEnabled(true);
			boxPrice.setEnabled(true);
			boxDiscount.setEnabled(true);
			btnProduct.setEnabled(true);
			btnStock.setEnabled(true);
			btnSave.setEnabled(true);
			taxRate.setEnabled(true);
		}
	}

	private AsyncCallback<List<Invoice>> invListCallback = new AsyncCallback<List<Invoice>>() {

		@Override
		public void onFailure(Throwable caught) {

		}

		@Override
		public void onSuccess(List<Invoice> result) {
			for (Invoice inv : result) {
				VchItem x = new VchItem();
				x.docRef = inv.docRef;
				x.invNo = inv.invNo;
				x.limitPaid = inv.totalAmt - inv.totalPaid;
				x.paidAmt = x.limitPaid;
				voucher.items.add(x);
			}
			refreshItem();
			refreshInvoice();
			// recordCount.setText(String.valueOf(result.size())
			// + " รายการ"
			// + (result.size() > RESULT_LIMITED ? " แสดงเพียง "
			// + RESULT_LIMITED + " รายการ" : ""));

		}
	};
	private Customer customer;

	AsyncCallback<Boolean> editCallback = new AsyncCallback<Boolean>() {

		@Override
		public void onSuccess(Boolean result) {
			if (result) {
				clearScreen();
				Window.alert("บันทึกเสร็จสิ้น");
			}
		}

		@Override
		public void onFailure(Throwable caught) {

		}
	};

	AsyncCallback<Customer> custCallback = new AsyncCallback<Customer>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(Customer result) {
			customer = result;
			if (mode == FormMode.Insert || mode == FormMode.Edit) {
				boolean valid = true;
				// if (customer.custBalance > customer.custLimit) {
				// Window.alert("มียอดค้างชำระเกินวงเงิน");
				// // clearScreen();
				// valid = false;
				// } else if (customer.custStatus.compareTo("2") > 0) {
				// Window.alert("สถานะผิดพลาด");
				// // clearScreen();
				// valid = false;
				// }
				if (valid) {
					voucher.contCode = result.contCode;
					voucher.contAddr = result.contact.label;
					Date today = new Date();
					// CalendarUtil.addDaysToDate(today, result.custDueDay);
					// invoice.dueDate = today;
					refreshInvoice();
					if (mode == FormMode.Insert)
						Library.getSaleService().searchInvoice(null, null,
								null, "D", null, true, null, result.contCode, "1",
								invListCallback);

				} else {
					clearScreen();
				}
			} else {
				refreshInvoice(); // กรณีเปิดดูอย่างเดียว
			}
		}
	};

	Voucher voucher;

	AsyncCallback<String> insInvCallback = new AsyncCallback<String>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(String result) {
			btnSave.setEnabled(true);
			btnSave2.setEnabled(true);
			Library.getSaleService().selectInvoice(Integer.valueOf(result),
					invCallback);
		}
	};

	AsyncCallback<Voucher> vchCallback = new AsyncCallback<Voucher>() {

		@Override
		public void onFailure(Throwable caught) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onSuccess(Voucher result) {
			if (result != null) {
				voucher = result;
				if (result.status.compareTo("0") > 0)
					setMode(FormMode.Open);
				else
					setMode(FormMode.Edit);
				// invoice = result;

				if (voucher.contCode != null)
					Library.getSaleService().selectCustomer(voucher.contCode,
							custCallback);
				refreshPayments();
				refreshItem();
				refreshInvoice();
			} else {
				clearScreen();
			}
		}

	};

	AsyncCallback<Invoice> invCallback = new AsyncCallback<Invoice>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(Invoice result) {
			if (result != null) {
				VchItem x = new VchItem();
				x.docRef = result.docRef;
				x.invNo = result.invNo;
				x.limitPaid = result.totalAmt - result.totalPaid;
				x.paidAmt = x.limitPaid;
				voucher.items.add(x);
				// if (result.status.compareTo("0") > 0)
				// setMode(FormMode.Open);
				// else
				// setMode(FormMode.Edit);
				// invoice = result;
				// if (invoice.contCode != null)
				// Library.getSaleService().selectCustomer(invoice.contCode,
				// custCallback);
				// refreshPayments();
				refreshItem();
				refreshInvoice();

			} else {
				clearScreen();
			}
		}
	};

	private VchItem curItem;

	AsyncCallback<Product> proCallback = new AsyncCallback<Product>() {
		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(Product result) {
			if (result != null) {
				// txtProName.setText(result.name);
				// boxQty.setValue(1.0);
				// boxPrice.setValue(result.sellPrice);
				// boxDiscount.setValue(result.discount);

				if (mode == FormMode.Insert || mode == FormMode.Edit) {
					if (curItem == null) {
						curItem = new VchItem();
						// invoice.items.add(curItem);

					}

					// curItem.invNo = invoice.invNo;
					// curItem.proCode = result.proCode;
					// curItem.qty = 1.0;
					// curItem.unitPrice = result.sellPrice;
					// curItem.proName = result.name;
					// curItem.discount = result.discount;
					// curItem.stkCode = result.stkCode;
					// curItem.vat = vat.get(Integer.parseInt(result.sellVAT));
					// curItem.unit = result.unit;
					// curItem.product = result;
					// curItem.stocks = result.stocks;
					refreshItem();
					refreshInvoice();
					boxQty.setFocus(true);
					boxQty.selectAll();
				}
			} else {
				Window.alert("ไม่มีข้อมูลสินค้า");
			}
		}
	};

	private Payment curPay;

	public void clearScreen() {
		voucher = new Voucher();
		// invList.clear();
		voucher.systemKind = "D";
		voucher.docuKind = "I";
		customer = new Customer();
		curItem = null;
		curPay = new Payment();
		curPay.payMethod = 1;
		txtPayMeth.setText("1");
		curPay.payMethodName = "เงินสดขาย";
		taxRate.setSelectedIndex(0);
		txtCheck.setVisible(false);
		boxCheckDate.setVisible(false);
		label_2.setVisible(false);
		label_3.setVisible(false);
		setMode(FormMode.Clear);
		// refreshPayments();
		refreshItem();
		refreshInvoice();
		refreshPayments();
	}

	private void refreshInvoice() {
		calcTax();
		txtDocRef.setText(voucher.docRef);
		if (customer.contact != null) {
			txtCustomer.setText(customer.contact.name);
		} else
			txtCustomer.setText(voucher.contAddr);
		txtContCode.setText(voucher.contCode);
		txtSaleDate.setValue(voucher.vchDate);
		txtAddr.setText(voucher.contAddr);

		lbTextTotal.setText(voucher.totalAmtText);
		txtTotalAmt.setValue(Library.moneyFormat(voucher.totalAmt));
		txtAmtPaid.setValue(Library.moneyFormat(voucher.amtPaid));
		txtTotalTax.setValue(Library.moneyFormat(voucher.totalTax));
		txtDiscount.setValue(Library.moneyFormat(voucher.spcDeduct));

		if (voucher.taxRate < 90) {
			txtTotalTax.setEnabled(false);
			if (voucher.taxRate == 0)
				taxRate.setSelectedIndex(0);
			else if (voucher.taxRate == 1)
				taxRate.setSelectedIndex(1);
			else if (voucher.taxRate == 3)
				taxRate.setSelectedIndex(2);
			else if (voucher.taxRate == 5)
				taxRate.setSelectedIndex(3);
		} else {
			taxRate.setSelectedIndex(4);
			txtTotalTax.setEnabled(true);
		}
		boxPayAmt.setValue(voucher.amtPaid);

		double bal = voucher.totalItem - voucher.amtPaid;
		txtBal.setValue(Library.moneyFormat(bal));
		// boxPayAmt.setValue(bal);
		// if (invoice.totalPaid == 0) {
		// btnSave.setText("อัพโหลด");
		// } else {
		// btnSave.setText("บันทึก");
		// }
	}

	private void refreshPayments() {
		if (mode == FormMode.Insert || mode == FormMode.Edit)
			calcPay();
		if (curPay == null) {
			curPay = new Payment();
			curPay.payMethod = 1;
			curPay.payMethodName = "เงินสดขาย";
			curPay.amt = voucher.amtPaid;
		}
		boxPayAmt.setValue(curPay.amt);
		txtPayMeth.setText(curPay.payMethod.toString());
		txtPayMethod.setText(curPay.payMethodName);
		txtCheck.setValue(curPay.chkCardNo);
		txtPayMeth.setValue(curPay.payMethod.toString());
		boxCheckDate.setValue(curPay.checkDate);
		payData.setList(voucher.payments);
		payData.refresh();
		refreshCheck();
	}

	private void calcPay() {

	}

	private void refreshItem() {
		// if (mode == FormMode.Insert || mode == FormMode.Edit)
		calcItem();
		if (curItem == null) {
			txtProCode.setText(null);
			txtProName.setText(null);
			boxQty.setValue(null);
			boxPrice.setValue(null);
			boxDiscount.setValue(null);
		} else {
			// txtProCode.setText(curItem.proCode);
			// txtProName.setText(curItem.proName);
			// boxQty.setValue(curItem.qty);
			// boxPrice.setValue(curItem.unitPrice);
			// boxDiscount.setValue(curItem.discount);
		}
		// txtTotal.setText(Library.moneyFormat(invoice.totalItem));
		// txtTotalVat.setText(Library.moneyFormat(invoice.totalVat));
		// double bal = voucher.totalItem - voucher.amtPaid;
		// txtBal.setValue(Library.moneyFormat(bal));
		// lbTextTotal.setText(Library.moneyText(invoice.totalAmt));
		itemData.setList(voucher.items);
		itemData.refresh();
	}

	private static FormVch panel;

	public static FormVch getPanel() {
		if (panel == null)
			panel = GWT.create(FormVch.class);
		return panel;
	}

	private static final String pWidth = "900px";

	private static final String pHeight = "500px";

	private final ListDataProvider<VchItem> itemData = new ListDataProvider<VchItem>();
	private final CellTable<VchItem> itemTable = new CellTable<VchItem>();
	private final SingleSelectionModel<VchItem> itemSelection = new SingleSelectionModel<VchItem>();

	private final ListDataProvider<Payment> payData = new ListDataProvider<Payment>();
	private final CellTable<Payment> payTable = new CellTable<Payment>();
	private final SingleSelectionModel<Payment> paySelection = new SingleSelectionModel<Payment>();

	private List<Double> vat;

	private final DateBox txtSaleDate;

	private final DateBox txtShipDate;

	private final TextArea txtAddr;

	private final TextArea txtShipTo;

	private final TextArea txtComment;

	private final TextBox txtDocRef;

	private final TextBox txtCustomer;

	private final TextBox txtCode;

	private final TextBox txtContCode;

	private final TextBox txtStatus;

	private final TextBox txtBalance;

	private final TextBox txtTotalPaid;

	private final TextBox txtTotalAmt;

	private final TextBox txtAmtPaid;

	private final TextBox txtDiscount;

	private final TextBox txtTotalTax;

	private final TextBox txtBal;

	private DoubleBox boxPayAmt = new DoubleBox();

	private TextBox txtPayMethod = new TextBox();

	private final TextBox txtCheck = new TextBox();

	private final TextBox txtPayMeth = new TextBox();

	private final DateBox boxCheckDate = new DateBox();

	private final Button btnContact;

	private final TextBox txtProCode = new TextBox();

	private final TextBox txtProName = new TextBox();

	private final DoubleBox boxQty = new DoubleBox();

	private final DoubleBox boxPrice = new DoubleBox();

	private final DoubleBox boxDiscount = new DoubleBox();

	private final Button btnProduct = new Button("?");

	private final Label lbFormMode;

	private final Label lbTextTotal = new Label();

	// private final Label lblDueDate;

	private final Button btnStock = new Button("เลือกคลัง");

	private final Button btnSave = new Button("อัพโหลด");

	private final Button btnSave2 = new Button("บันทึก");

	private final Button btnSearch = new Button("ค้นหา");

	private final Button btnDelItem = new Button("ลบรายการ");

	private final Button btnPayRemove = new Button("ลบ");

	private final Label label_2 = new Label("เลขที่เช็ค");

	private final Label label_3 = new Label("วันที่บัตร");

	private final ListBox taxRate;

	// private final List<VchItem> invList = new ArrayList<VchItem>();

	AsyncCallback<List<TaxCalc>> taxCallback = new AsyncCallback<List<TaxCalc>>() {

		@Override
		public void onFailure(Throwable caught) {
			// TODO Auto-generated method stub

		}

		@Override
		public void onSuccess(List<TaxCalc> result) {
			taxRate.clear();
			for (TaxCalc tax : result)
				taxRate.addItem(tax.descript, tax.percent.toString());
		}
	};

	public FormVch() {
		setSize(pWidth, pHeight);

		TabPanel tabPanel = new TabPanel();
		add(tabPanel, 0, 100);
		tabPanel.setSize(pWidth, "380px");

		AbsolutePanel invPanel = new AbsolutePanel();
		invPanel.setSize(pWidth, "360px");
		tabPanel.add(invPanel, "ใบเสร็จ");

		tabPanel.add(createItemPanel(), "เลือกบิล");
		tabPanel.add(createPaymentPanel(), "ชำระเงิน");

		Label label_1 = new Label("วันที่ใบเสร็จ");
		invPanel.add(label_1, 10, 10);

		Label label_2 = new Label("วันที่ชำระเงิน");
		invPanel.add(label_2, 10, 41);

		Label label_5 = new Label("ที่อยู่จัดส่ง");
		invPanel.add(label_5, 348, 103);

		Label label_6 = new Label("หมายเหตุ");
		invPanel.add(label_6, 348, 200);

		Label lblNewLabel = new Label("ที่อยู่ใบกำกับภาษี");
		invPanel.add(lblNewLabel, 352, 10);

		invPanel.add(lbTextTotal, 348, 320);
		// add(lbTextTotal, 625, 15);

		txtSaleDate = new DateBox();
		txtSaleDate.setValue(new Date());
		txtSaleDate.setFormat(new DefaultFormat(Library.DATE_FORMAT));
		invPanel.add(txtSaleDate, 114, 7);
		txtSaleDate.setSize("80px", "18px");

		txtShipDate = new DateBox();
		// txtShipDate.setValue(new Date());
		txtShipDate.setFormat(new DefaultFormat(Library.DATE_FORMAT));
		invPanel.add(txtShipDate, 114, 38);
		txtShipDate.setSize("80px", "18px");

		txtAddr = new TextArea();
		invPanel.add(txtAddr, 480, 10);
		txtAddr.setSize("350px", "85px");

		txtShipTo = new TextArea();
		invPanel.add(txtShipTo, 480, 103);
		txtShipTo.setSize("350px", "85px");

		txtComment = new TextArea();
		invPanel.add(txtComment, 480, 200);
		txtComment.setSize("350px", "85px");

		// Button btnCustomer = new Button("?");
		// invPanel.add(btnCustomer, 235, 98);
		// btnCustomer.setSize("30px", "24px");
		// btnCustomer.addClickHandler(new ClickHandler() {
		// public void onClick(ClickEvent event) {
		// LookupDialog.show("เลือกลูกค้า", "contCode", txtContCode);
		// }
		// });

		btnSave.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				// if (invoice.payments.size() != 0)
				// invoice.upload = 1;
				btnSave.setEnabled(false);
				// if (mode == FormMode.Insert)
				// voucher.items = invList;
				truncateItem();
				Library.getAccService().insertVoucher(voucher, editCallback);
				// Library.getSaleService().insertInvoice(invoice,
				// insInvCallback);
				// else
				// Library.getSaleService().updateInvoice(invoice,
				// insInvCallback);
			}
		});
		add(btnSave, 806, 44);
		btnSave.setSize("88px", "39px");
		btnSave.setText("อัพโหลด");

		btnSearch.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				// LookupInvDlg.show("เลือกบิล", "invNo", txtCode);
				LookupDialog.show("เลือก Voucher", "voucherNo", txtCode);
			}
		});

		btnSearch.setText("ค้นหา");
		add(btnSearch, 10, 10);
		btnSearch.setSize("88px", "26px");

		Label label = new Label("เลขที่");
		add(label, 108, 14);
		txtDocRef = new TextBox();
		add(txtDocRef, 141, 11);
		txtDocRef.setSize("100px", "16px");

		Label label1 = new Label("ลูกค้า");
		add(label1, 108, 44);
		txtCustomer = new TextBox();
		txtCustomer.setStyleName("gwt-TextBoxR");
		txtCustomer.setReadOnly(true);
		add(txtCustomer, 234, 41);
		txtCustomer.setSize("180px", "18px");

		Label label2 = new Label("วงเงินคงเหลือ");
		add(label2, 65, 73);

		Label label4 = new Label("ลูกค้าชำระ");
		add(label4, 440, 72);

		// Label label3 = new Label("ชำระแล้ว");
		// add(label3, 625, 44);

		Label lblNewLabel_1 = new Label("ยอดรวมใบเสร็จ");
		add(lblNewLabel_1, 440, 2);

		Label lblNewLabel_6 = new Label("หักลดพิเศษ");
		add(lblNewLabel_6, 440, 46);

		Label label_7 = new Label("ภาษีหัก ณ ที่จ่าย");
		add(label_7, 440, 27);

		txtCode = new TextBox();
		txtCode.setReadOnly(true);
		add(txtCode, 255, 10);
		txtCode.setSize("19px", "18px");
		txtCode.setVisible(false);
		txtCode.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					Library.getAccService().selectVoucher(
							Integer.valueOf(txtCode.getText()), vchCallback);
				} else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
					clearScreen();
				} else if (event.isControlKeyDown()
						&& event.getNativeKeyCode() == ' ') {
					// btnSearchContact.click();
				}
			}
		});

		txtContCode = new TextBox();
		txtContCode.addValueChangeHandler(new ValueChangeHandler<String>() {
			public void onValueChange(ValueChangeEvent<String> event) {
				Library.getSaleService().selectCustomer(txtContCode.getText(),
						custCallback);
			}
		});
		txtContCode.setText("999999");
		add(txtContCode, 141, 41);
		txtContCode.setSize("50px", "16px");
		txtContCode.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					if (mode != FormMode.Edit)
						setMode(FormMode.Insert);
					Library.getSaleService().selectCustomer(
							txtContCode.getText(), custCallback);
					// selectContactDebter();
				} else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
					clearScreen();
				} else if (event.isControlKeyDown()
						&& event.getNativeKeyCode() == ' ') {
					btnContact.click();
				}
			}
		});

		btnContact = new Button("?");
		add(btnContact, 205, 41);
		btnContact.setSize("24px", "24px");
		btnContact.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				LookupDialog.show("เลือกลูกค้า", "contCode", txtContCode);
			}
		});

		txtStatus = new TextBox();
		txtStatus.setStyleName("gwt-TextBoxR");
		txtStatus.setReadOnly(true);
		add(txtStatus, 310, 12);
		txtStatus.setSize("100px", "18px");
		txtStatus.setVisible(false);

		txtBalance = new TextBox();
		txtBalance.setStyleName("gwt-TextBoxR");
		txtBalance.setText("0.0");
		txtBalance.setReadOnly(true);
		txtBalance.setMaxLength(10);
		txtBalance.setAlignment(TextAlignment.RIGHT);
		add(txtBalance, 141, 71);
		txtBalance.setSize("100px", "16px");

		txtTotalPaid = new TextBox();
		txtTotalPaid.setVisible(false);
		txtTotalPaid.setStyleName("gwt-TextBoxYellow");
		txtTotalPaid.setText("0.0");
		txtTotalPaid.setReadOnly(true);
		txtTotalPaid.setMaxLength(10);
		txtTotalPaid.setAlignment(TextAlignment.RIGHT);
		add(txtTotalPaid, 691, 42);
		txtTotalPaid.setSize("105px", "16px");

		lbFormMode = new Label("");
		add(lbFormMode, 260, 10);
		lbFormMode.setVisible(false);

		Button btnClear = new Button("เคลียร์");
		btnClear.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				clearScreen();
			}
		});
		add(btnClear, 10, 41);
		btnClear.setSize("88px", "26px");

		txtBal = new TextBox();
		txtBal.setVisible(false);
		txtBal.setText("0.0");
		txtBal.setStyleName("gwt-TextBoxYellow");
		txtBal.setReadOnly(true);
		txtBal.setMaxLength(10);
		txtBal.setAlignment(TextAlignment.RIGHT);
		add(txtBal, 691, 69);
		txtBal.setSize("105px", "16px");

		// Label label_8 = new Label("คงค้าง");
		// add(label_8, 625, 69);
		// label_8.setSize("51px", "18px");

		btnSave2.setText("ยืนยันชำระ");
		add(btnSave2, 806, 2);
		btnSave2.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (boxPayAmt.getValue() > 0) {
					insertPayment();
				}
				// invoice.upload = 1;
				btnSave2.setEnabled(false);
				// if (mode == FormMode.Insert)
				// Library.getSaleService().insertInvoice(invoice,
				// insInvCallback);
				// else
				// Library.getSaleService().updateInvoice(invoice,
				// insInvCallback);
			}
		});

		btnSave2.setSize("88px", "39px");

		// Label label_7 = new Label("รวมเงิน");
		// add(label_7, 625, 16);
		// label_7.setSize("49px", "18px");

		txtAmtPaid = new TextBox();
		txtAmtPaid.setStyleName("gwt-TextBoxR");
		txtAmtPaid.setText("0.0");
		txtAmtPaid.setReadOnly(true);
		txtAmtPaid.setMaxLength(10);
		txtAmtPaid.setAlignment(TextAlignment.RIGHT);
		add(txtAmtPaid, 540, 72);
		txtAmtPaid.setSize("104px", "16px");

		txtTotalTax = new TextBox();
		// txtTotalVat.setStyleName("gwt-TextBoxR");
		txtTotalTax.setText("0.0");
		txtTotalTax.setReadOnly(false);
		txtTotalTax.setMaxLength(10);
		txtTotalTax.setAlignment(TextAlignment.RIGHT);
		add(txtTotalTax, 540, 24);
		txtTotalTax.setSize("100px", "16px");
		txtTotalTax.addValueChangeHandler(new ValueChangeHandler<String>() {
			public void onValueChange(ValueChangeEvent<String> event) {
				voucher.totalTax = Double.parseDouble(txtTotalTax.getValue());
				refreshInvoice();
			}
		});

		txtTotalAmt = new TextBox();
		txtTotalAmt.setStyleName("gwt-TextBoxR");
		txtTotalAmt.setText("0.0");
		txtTotalAmt.setReadOnly(true);
		txtTotalAmt.setMaxLength(10);
		txtTotalAmt.setAlignment(TextAlignment.RIGHT);
		add(txtTotalAmt, 540, 2);
		txtTotalAmt.setSize("104px", "16px");

		txtDiscount = new TextBox();
		txtDiscount.setText("0.0");
		txtDiscount.setMaxLength(10);
		txtDiscount.setAlignment(TextAlignment.RIGHT);
		add(txtDiscount, 540, 48);
		txtDiscount.setSize("100px", "16px");

		txtDiscount.addValueChangeHandler(new ValueChangeHandler<String>() {
			public void onValueChange(ValueChangeEvent<String> event) {
				voucher.spcDeduct = Double.valueOf(txtDiscount.getValue());
				voucher.amtPaid = voucher.totalAmt - voucher.totalTax
						- voucher.spcDeduct;
				refreshInvoice();
			}
		});

		taxRate = new ListBox();
		taxRate.setSelectedIndex(0);
		add(taxRate, 270, 10);
		taxRate.setSize("140px", "22px");
		taxRate.addChangeHandler(new ChangeHandler() {

			@Override
			public void onChange(ChangeEvent event) {
				// TotalAmt / 1 + vat = x (1.00 + vat)
				voucher.taxRate = Double.parseDouble(taxRate.getValue(taxRate
						.getSelectedIndex()));
				// txtTotalVat.setValue(Library.moneyFormat(voucher.));
				refreshInvoice();
			}
		});

		// Label label_11 = new Label("ภาษีหัก ณ.ที่จ่าย");
		// add(label_11, 265, 10);
		tabPanel.selectTab(0);
		Library.getStkService().selectVAT(vatCallback);
		clearScreen();
		Library.getAccService().selectTaxCalc(taxCallback);

	}

	private Panel createPaymentPanel() {
		VerticalPanel vPanel1 = new VerticalPanel();

		// paySelection
		// .addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
		// @Override
		// public void onSelectionChange(SelectionChangeEvent event) {
		// curPay = paySelection.getSelectedObject();
		// refreshPayments();
		// }
		// });

		vPanel1.setSize("100%", "100%");
		AbsolutePanel editPanel = new AbsolutePanel();
		editPanel.setSize("880px", "80px");
		vPanel1.add(editPanel);

		Label label = new Label("ชำระ");
		editPanel.add(label, 10, 10);

		boxPayAmt.setAlignment(TextAlignment.RIGHT);
		editPanel.add(boxPayAmt, 91, 7);
		boxPayAmt.setSize("100px", "18px");
		boxPayAmt.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
					insertPayment();
				} else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
				} else if (event.isControlKeyDown()
						&& event.getNativeKeyCode() == ' ') {
				}
			}
		});

		Label label_1 = new Label("วิธีชำระ");
		editPanel.add(label_1, 10, 37);

		txtPayMethod.setStyleName("gwt-TextBoxR");
		txtPayMethod.setReadOnly(true);
		txtPayMethod.setText("เงินสดขาย");
		editPanel.add(txtPayMethod, 90, 34);
		txtPayMethod.setSize("180px", "18px");

		Button btnPayMeth = new Button("?");
		editPanel.add(btnPayMeth, 275, 33);
		btnPayMeth.setSize("24px", "24px");
		btnPayMeth.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				LookupDialog.show("เลือกประเภทการชำระ", "payMeth", txtPayMeth,
						txtPayMethod);
			}
		});

		ScrollPanel paymentPanel = new ScrollPanel();
		paymentPanel.setSize("895px", "280px");
		vPanel1.add(paymentPanel);

		payTable.setStyleName("table");
		paymentPanel.setWidget(payTable);

		payData.addDataDisplay(payTable);
		payTable.setPageSize(10);
		payTable.setTableLayoutFixed(true);
		payTable.setAccessKey('x');
		// itemTable.setSize("100%", "100%");
		payTable.setHeight("100%");
		// payTable.setWidth("100%", true);
		payTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);

		TextColumn<Payment> colPayDate = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				if (object.payDate == null)
					return null;
				else
					return Library.DATE_FORMAT.format(object.payDate);
			}
		};
		payTable.addColumn(colPayDate, "วันที่ชำระเงิน");
		payTable.setColumnWidth(colPayDate, "100px");

		TextColumn<Payment> colPayMeth = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				return object.payMethodName;
			}
		};
		payTable.addColumn(colPayMeth, "วิธีชำระ");
		payTable.setColumnWidth(colPayMeth, "150px");

		TextColumn<Payment> colPayAmt = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				return Library.moneyFormat(object.amt);
			}
		};
		colPayAmt.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		payTable.addColumn(colPayAmt, "Amount");
		payTable.setColumnWidth(colPayAmt, "50px");

		TextColumn<Payment> colCard = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				return object.chkCardNo;
			}
		};
		payTable.addColumn(colCard, "เลขที่เช็ค/บัตร");
		payTable.setColumnWidth(colCard, "100px");

		TextColumn<Payment> colExpDate = new TextColumn<Payment>() {
			@Override
			public String getValue(Payment object) {
				if (object.checkDate == null)
					return null;
				else
					return Library.DATE_FORMAT.format(object.checkDate);
			}
		};
		payTable.addColumn(colExpDate, "วันที่เช็ค");
		payTable.setColumnWidth(colExpDate, "100px");

		editPanel.add(txtCheck, 473, 6);
		txtCheck.setSize("100px", "18px");
		txtCheck.setVisible(false);

		label_2.setVisible(false);

		editPanel.add(label_2, 392, 10);

		txtPayMeth.setReadOnly(true);
		txtPayMeth.setVisible(false);
		editPanel.add(txtPayMeth, 252, 33);
		txtPayMeth.setSize("20px", "18px");
		txtPayMeth.setText("1");
		txtPayMeth.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				refreshCheck();
			}
		});

		editPanel.add(label_3, 392, 37);
		label_3.setSize("120px", "18px");
		label_3.setVisible(false);

		boxCheckDate.setFormat(new DefaultFormat(Library.DATE_FORMAT));
		editPanel.add(boxCheckDate, 473, 34);
		boxCheckDate.setSize("105px", "18px");
		boxCheckDate.setVisible(false);

		Button btnPay = new Button("insert");
		btnPay.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				insertPayment();
			}
		});

		editPanel.add(btnPay, 720, 7);
		btnPay.setSize("90px", "24px");

		btnPayRemove.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				deletePayment();
			}

		});
		btnPayRemove.setTabIndex(-1);

		editPanel.add(btnPayRemove, 720, 40);
		btnPayRemove.setSize("90px", "24px");

		payTable.setSelectionModel(paySelection);

		paySelection
				.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
					@Override
					public void onSelectionChange(SelectionChangeEvent event) {
						curPay = paySelection.getSelectedObject();
						refreshPayments();
					}
				});

		// DoubleBox doubleBox = new DoubleBox();
		// editPanel.add(doubleBox, 95, 10);
		//
		// TextBox textBox = new TextBox();
		// editPanel.add(textBox, 91, 42);
		//
		// Label lblNewLabel_5 = new Label("ส่วนลดพิเศษ");
		// editPanel.add(lblNewLabel_5, 10, 10);
		return vPanel1;
	}

	private Panel createItemPanel() {
		VerticalPanel vPanel = new VerticalPanel();
		vPanel.setSize("100%", "100%");
		AbsolutePanel editPanel = new AbsolutePanel();
		editPanel.setSize("895px", "50px");
		vPanel.add(editPanel);
		ScrollPanel listPanel = new ScrollPanel();
		listPanel.setSize("895px", "280px");
		vPanel.add(listPanel);

		itemTable.setStyleName("table");
		listPanel.setWidget(itemTable);
		itemTable.setSelectionModel(itemSelection);

		itemSelection
				.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
					@Override
					public void onSelectionChange(SelectionChangeEvent event) {
						curItem = itemSelection.getSelectedObject();
						refreshItem();
					}
				});
		Column<VchItem, Boolean> colSelect = new Column<VchItem, Boolean>(
				new CheckboxCell()) {
			@Override
			public Boolean getValue(VchItem object) {
				return object.selected;
			}
		};
		colSelect.setFieldUpdater(new FieldUpdater<VchItem, Boolean>() {

			@Override
			public void update(int index, VchItem object, Boolean value) {
				object.selected = value;
				refreshItem();
				refreshInvoice();
			}
		});
		// colSelect.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		itemTable.addColumn(colSelect, "เลือก");
		itemTable.setColumnWidth(colSelect, "50px");

		TextColumn<VchItem> colProCode = new TextColumn<VchItem>() {
			@Override
			public String getValue(VchItem object) {
				return object.docRef;
			}
		};
		// colProCode.setCellStyleNames("table");
		itemTable.addColumn(colProCode, "เลขที่บิล");
		itemTable.setColumnWidth(colProCode, "95px");

		TextColumn<VchItem> colTotalItem = new TextColumn<VchItem>() {
			@Override
			public String getValue(VchItem object) {
				return Library.moneyFormat(object.limitPaid);
			}
		};
		colTotalItem.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		itemTable.addColumn(colTotalItem, "ยอดยกมา");
		itemTable.setColumnWidth(colTotalItem, "80px");

		Column<VchItem, String> colPaidAmt = new Column<VchItem, String>(
				new TextInputCell()) {
			@Override
			public String getValue(VchItem object) {
				return Library.moneyFormat(object.paidAmt);
			}
		};
		colPaidAmt.setFieldUpdater(new FieldUpdater<VchItem, String>() {

			@Override
			public void update(int index, VchItem object, String value) {
				object.paidAmt = Double.parseDouble(value);
				refreshItem();
				refreshInvoice();
			}
		});
		colPaidAmt.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		itemTable.addColumn(colPaidAmt, "ชำระจริง");
		itemTable.setColumnWidth(colPaidAmt, "150px");

		TextColumn<VchItem> colRemain = new TextColumn<VchItem>() {
			@Override
			public String getValue(VchItem object) {
				return Library.moneyFormat(object.remain);
			}
		};
		colRemain.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
		itemTable.addColumn(colRemain, "คงเหลือ");
		itemTable.setColumnWidth(colRemain, "80px");

		// itemData.setList(itemList);
		itemData.addDataDisplay(itemTable);
		itemTable.setPageSize(40);
		itemTable.setTableLayoutFixed(true);
		itemTable.setAccessKey('x');
		itemTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
		itemTable.setHeight("100%");
		// itemTable.setWidth("100%", true);

		btnProduct.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				LookupInvDlg.show("เลือกบิล", txtProCode, "D", true, txtContCode.getValue(),
						"1");
			}
		});
		editPanel.add(btnProduct, 204, 4);
		btnProduct.setSize("27px", "24px");

		editPanel.add(txtProCode, 70, 4);
		txtProCode.setSize("120px", "18px");
		txtProCode.addValueChangeHandler(new ValueChangeHandler<String>() {
			public void onValueChange(ValueChangeEvent<String> event) {
				Library.getSaleService().selectInvoice(
						Integer.parseInt(txtProCode.getText()), invCallback);
			}
		});

		txtProCode.addKeyDownHandler(new KeyDownHandler() {
			public void onKeyDown(KeyDownEvent event) {
				if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {

					curItem = findList(txtProCode.getText());

					if (curItem == null) {
						Library.getSaleService().selectInvoice(
								Integer.parseInt(txtProCode.getText()),
								invCallback);
					} else {
						// Window.alert(curItem.invNo.toString());
					}
				} else if (event.getNativeKeyCode() == KeyCodes.KEY_ESCAPE) {
					curItem = null;
					refreshItem();
					refreshInvoice();
				} else if (event.isControlKeyDown()
						&& event.getNativeKeyCode() == ' ') {
					btnProduct.click();
				}
			}
		});
		Label lblNewLabel_2 = new Label("เลขที่บิล");
		editPanel.add(lblNewLabel_2, 8, 9);

		// editPanel.add(txtProName, 330, 4);
		// txtProName.setSize("337px", "18px");
		//
		// Label lblNewLabel_3 = new Label("ชื่อสินค้า");
		// editPanel.add(lblNewLabel_3, 260, 10);
		//
		// Label lblNewLabel_4 = new Label("จำนวน");
		// editPanel.add(lblNewLabel_4, 8, 39);

		// editPanel.add(boxQty, 70, 36);
		// boxQty.setSize("50px", "18px");
		// boxQty.addValueChangeHandler(new ValueChangeHandler<Double>() {
		// @Override
		// public void onValueChange(ValueChangeEvent<Double> event) {
		// // curItem.qty = event.getValue();
		// refreshItem();
		// refreshInvoice();
		// }
		// });
		// boxQty.addKeyDownHandler(new KeyDownHandler() {
		// public void onKeyDown(KeyDownEvent event) {
		// if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
		// boxPrice.setFocus(true);
		// boxPrice.selectAll();
		// }
		// }
		// });
		//
		// Label label = new Label("ราคา");
		// editPanel.add(label, 130, 39);
		//
		// editPanel.add(boxPrice, 163, 36);
		// boxPrice.setSize("80px", "18px");
		// boxPrice.addValueChangeHandler(new ValueChangeHandler<Double>() {
		// @Override
		// public void onValueChange(ValueChangeEvent<Double> event) {
		// // curItem.unitPrice = event.getValue();
		// refreshItem();
		// refreshInvoice();
		//
		// }
		// });
		// boxPrice.addKeyDownHandler(new KeyDownHandler() {
		// public void onKeyDown(KeyDownEvent event) {
		// if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
		// boxDiscount.setFocus(true);
		// boxDiscount.selectAll();
		// }
		// }
		// });
		//
		// Label label1 = new Label("สวนลด(%)");
		// editPanel.add(label1, 257, 39);
		// boxDiscount.setAlignment(TextAlignment.RIGHT);
		//
		// editPanel.add(boxDiscount, 330, 36);
		// boxDiscount.setSize("35px", "18px");
		// boxDiscount.addValueChangeHandler(new ValueChangeHandler<Double>() {
		// @Override
		// public void onValueChange(ValueChangeEvent<Double> event) {
		// // curItem.discount = event.getValue();
		// refreshItem();
		// refreshInvoice();
		//
		// }
		// });
		// boxDiscount.addKeyDownHandler(new KeyDownHandler() {
		// public void onKeyDown(KeyDownEvent event) {
		// if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
		// btnStock.setFocus(true);
		// }
		// }
		// });
		//
		// Button btnDiscount = new Button("ลด");
		// btnDiscount.addClickHandler(new ClickHandler() {
		// public void onClick(ClickEvent event) {
		// OverwriteLevel.show(FormVch.this);
		// }
		// });
		// editPanel.add(btnDiscount, 375, 36);
		// btnDiscount.setSize("40px", "24px");

		// Label label_1 = new Label("คลัง");
		// editPanel.add(label_1, 520, 39);
		// label_1.setSize("36px", "18px");

		// editPanel.add(txtStkLoc, 517, 36);
		// txtStkLoc.setSize("50px", "18px");
		//
		// editPanel.add(txtStkCode, 617, 36);
		// txtStkCode.setSize("50px", "18px");
		// txtStkCode.setVisible(false);

		// editPanel.add(btnStock, 450, 36);
		// btnStock.setSize("100px", "24px");
		// btnStock.addClickHandler(new ClickHandler() {
		// public void onClick(ClickEvent event) {
		// StockPopup.popup.open(curItem);
		// }
		// });
		// StockPopup.popup.setTable(itemTable);

		btnDelItem.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if (mode == FormMode.Insert || mode == FormMode.Edit) {
					voucher.items.remove(curItem);
					curItem = null;
					refreshItem();
					refreshInvoice();
				}
			}
		});
		btnDelItem.setTabIndex(-1);
		editPanel.add(btnDelItem, 700, 10);
		btnDelItem.setSize("100px", "24px");
		return vPanel;
	}

	private VchItem findList(String proCode) {
		VchItem inv = null;
		if (voucher.items.size() > 0) {
			// int i = invList.size() - 1;
			for (int i = voucher.items.size() - 1; i >= 0 && inv == null; i--) {
				if (proCode.equals(voucher.items.get(i).invNo.toString()))
					inv = voucher.items.get(i);
			}
		}
		if (inv != null)
			itemSelection.setSelected(inv, true);
		return inv;
	}

	@Override
	public void execute(int execode) {
		// TODO Auto-generated method stub
	}

	private void calcItem() {
		voucher.totalAmt = 0.0;
		for (VchItem item : voucher.items)
			if (item.selected) {
				if (item.limitPaid != null && item.paidAmt > item.limitPaid)
					item.paidAmt = item.limitPaid;
				voucher.totalAmt += item.paidAmt;
				if (item.limitPaid != null)
					item.remain = item.limitPaid - item.paidAmt;
				// if (item.dcLevel > 0)
				// item.discount = Library.discountSeries(item.product,
				// item.dcLevel);

				// totalItem = item.qty * item.unitPrice;
				// price = totalItem * (100 - item.discount);
				// if (item.product.minPrice > 0
				// && item.unitPrice < item.product.minPrice)
				// item.unitPrice = item.product.minPrice;
				// item.total = Math.round(price) / 100.0;
				// item.vatAmt = item.total * item.vat;
				// invoice.totalVat += item.vatAmt;
				// invoice.totalItem += item.total;

			}
		itemTable.redraw();

		voucher.totalAmt = Math.round(voucher.totalAmt * 100) / 100.0;
		// InvItem item = itemSelection.getSelectedObject();
		// if (item == null && itemList.size() > 0)
		// itemSelection.setSelected(itemList.get(0), true);
		// item = itemSelection.getSelectedObject();
	}

	AsyncCallback<List<Double>> vatCallback = new AsyncCallback<List<Double>>() {

		@Override
		public void onFailure(Throwable caught) {
			Window.alert(caught.getMessage());
		}

		@Override
		public void onSuccess(List<Double> result) {
			if (result != null) {
				vat = result;
			}

		}
	};

	private void insertPayment() {
		if (mode == FormMode.Insert || mode == FormMode.Edit) {
			if ((txtCheck.getText() != null || !txtCheck.isVisible())
					&& (boxCheckDate.getValue() != null || !boxCheckDate
							.isVisible())) {
				curPay.amt = boxPayAmt.getValue();

				if (curPay == null && curPay.amt == null)
					curPay.amt = 0.0;
				// curPay.payDate = boxCheckDate.getValue();
				curPay.checkDate = boxCheckDate.getValue();
				curPay.payMethod = Integer.parseInt(txtPayMeth.getText());
				curPay.payMethodName = txtPayMethod.getText();
				curPay.chkCardNo = txtCheck.getText();
				curPay.systemKind = voucher.systemKind;
				double x = voucher.amtPaid;
				if (Library.compare(curPay.amt, x) <= 0) {
					if (curPay.payMethod != 0)
						voucher.amtPaid += curPay.amt;
					voucher.payments.add(curPay);
					curPay = null;
					refreshPayments();
					refreshInvoice();
				} else {
					Window.alert("ชำระเกินยอด " + Library.moneyFormat(x)
							+ curPay.amt);
				}

			} else {
				Window.alert("ข้อมูลการชำระไม่ครบ");
			}
		} else {
			Window.alert("สถานะ ชำระไม่ได้แล้ว");
		}

	}

	private void deletePayment() {
		if (mode == FormMode.Insert || mode == FormMode.Edit) {
			voucher.payments.remove(curPay);
			// if (curPay.payMethod != null && !curPay.payMethod.equals("00"))
			// invoice.totalPaid -= curPay.amt;
			refreshPayments();
			refreshInvoice();
		}
	}

	private void truncateItem() {
		List<VchItem> temp = voucher.items;
		voucher.items = new ArrayList<VchItem>();
		for (VchItem item : temp)
			if (item.selected) {
				voucher.items.add(item);
			}
	}

	public void calcTax() {
		if (mode == FormMode.Edit || mode == FormMode.Insert) {
			if (voucher.taxRate < 90) {
				double rate = Double.parseDouble(taxRate.getValue(taxRate
						.getSelectedIndex()));
				// Window.alert("tax = "+ rate + "%");
				double vat = 7;
				voucher.totalItem = voucher.totalAmt / ((100 + vat) / 100.0);

				voucher.totalVat = voucher.totalItem * vat;

				voucher.totalTax = voucher.totalItem * rate / 100;

				voucher.totalTax *= 100;
				voucher.totalTax = Math.round(voucher.totalTax) / 100.0;
				voucher.amtPaid = voucher.totalAmt - voucher.totalTax
						- voucher.spcDeduct;
			}
		}
	}

	public void refreshCheck() {
		txtCheck.setVisible(txtPayMeth.getText().equals("2"));
		label_2.setVisible(txtCheck.isVisible());
		boxCheckDate.setVisible(txtPayMeth.getText().equals("2")
				|| txtPayMeth.getText().equals("3")
				|| txtPayMeth.getText().equals("4")
				|| txtPayMeth.getText().equals("5")
				|| txtPayMeth.getText().equals("6")
				|| txtPayMeth.getText().equals("7")
				|| txtPayMeth.getText().compareTo("22") >= 0);
		label_3.setVisible(boxCheckDate.isVisible());
		if (txtPayMeth.getText().equals("2")) {
			label_3.setText("วันที่เช็ค");
		}
		if (txtPayMeth.getText().equals("3")
				|| txtPayMeth.getText().equals("4")
				|| txtPayMeth.getText().equals("5")
				|| txtPayMeth.getText().equals("6")) {
			label_3.setText("วันที่บัตรเครดิต");
		}
		if (txtPayMeth.getText().equals("7")
				|| txtPayMeth.getText().compareTo("22") >= 0) {
			label_3.setText("วันที่โอน");
		}
	}
}
